package com.example.demo.format;

import com.example.demo.web.rest.errors.NestedException;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.DeserializationConfig.Feature;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.codehaus.jackson.map.util.JSONPObject;
import org.codehaus.jackson.type.JavaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

public class JsonMapper {
    private final static Logger logger = LoggerFactory.getLogger(JsonMapper.class);
    private ObjectMapper mapper = new ObjectMapper();

    public JsonMapper(Inclusion inclusion) {
        this.mapper.setSerializationInclusion(inclusion);
        this.mapper.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        this.mapper.configure(Feature.FAIL_ON_NUMBERS_FOR_ENUMS, true);
    }

    public static JsonMapper buildNormalMapper() {
        return new JsonMapper(Inclusion.ALWAYS);
    }

    public static JsonMapper buildNonNullMapper() {
        return new JsonMapper(Inclusion.NON_NULL);
    }

    public static JsonMapper buildNonDefaultMapper() {
        return new JsonMapper(Inclusion.NON_DEFAULT);
    }

    public static JsonMapper buildNonEmptyMapper() {
        return new JsonMapper(Inclusion.NON_EMPTY);
    }

    public String toJson(Object object) {
        try {
            return this.mapper.writeValueAsString(object);
        } catch (IOException var3) {
            throw NestedException.wrap(var3);
        }
    }

    public <T> T fromJson(String jsonString, Class<T> clazz) {
        if (StringUtils.isEmpty(jsonString)) {
            return null;
        } else {
            try {
                return this.mapper.readValue(jsonString, clazz);
            } catch (IOException var4) {
                throw NestedException.wrap(var4);
            }
        }
    }

    public <T> T fromJson(String jsonString, JavaType javaType) {
        if (StringUtils.isEmpty(jsonString)) {
            return null;
        } else {
            try {
                return this.mapper.readValue(jsonString, javaType);
            } catch (IOException var4) {
                throw NestedException.wrap(var4);
            }
        }
    }

    public <T> T fromJson(String jsonString, Class<?> parametrized, Class... parameterClasses) {
        return this.fromJson(jsonString, this.constructParametricType(parametrized, parameterClasses));
    }

    public <T> List<T> fromJsonToList(String jsonString, Class<T> classMeta) {
        return this.fromJson(jsonString, this.constructParametricType(List.class, classMeta));
    }

    public <T> T fromJson(JsonNode node, Class<?> parametrized, Class... parameterClasses) {
        JavaType javaType = this.constructParametricType(parametrized, parameterClasses);

        try {
            return this.mapper.readValue(node, javaType);
        } catch (IOException var6) {
            throw NestedException.wrap(var6);
        }
    }

    public <T> T pathAtRoot(String json, String path, Class<?> parametrized, Class... parameterClasses) {
        JsonNode rootNode = this.parseNode(json);
        JsonNode node = rootNode.path(path);
        return this.fromJson(node, parametrized, parameterClasses);
    }

    public <T> T pathAtRoot(String json, String path, Class<T> clazz) {
        JsonNode rootNode = this.parseNode(json);
        JsonNode node = rootNode.path(path);
        return this.fromJson(node, clazz);
    }

    public JavaType constructParametricType(Class<?> parametrized, Class... parameterClasses) {
        return this.mapper.getTypeFactory().constructParametricType(parametrized, parameterClasses);
    }

    public <T> T update(T object, String jsonString) {
        try {
            return this.mapper.readerForUpdating(object).readValue(jsonString);
        } catch (IOException var5) {
            logger.warn("update json string:" + jsonString + " to object:" + object + " error.", var5);
        }

        return null;
    }

    public String toJsonP(String functionName, Object object) {
        return this.toJson(new JSONPObject(functionName, object));
    }

    public void setEnumUseToString(boolean value) {
        this.mapper.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, value);
        this.mapper.configure(Feature.READ_ENUMS_USING_TO_STRING, value);
    }

    public ObjectMapper getMapper() {
        return this.mapper;
    }

    public JsonNode parseNode(String json) {
        try {
            return this.mapper.readValue(json, JsonNode.class);
        } catch (IOException var3) {
            throw NestedException.wrap(var3);
        }
    }

    public static String toNormalJson(Object object) {
        return (new JsonMapper(Inclusion.ALWAYS)).toJson(object);
    }

    public static String toNonNullJson(Object object) {
        return (new JsonMapper(Inclusion.NON_NULL)).toJson(object);
    }

    public static String toNonDefaultJson(Object object) {
        return (new JsonMapper(Inclusion.NON_DEFAULT)).toJson(object);
    }

    public static String toNonEmptyJson(Object object) {
        return (new JsonMapper(Inclusion.NON_EMPTY)).toJson(object);
    }

    private void setDateFormat(String dateFormat) {
        this.mapper.setDateFormat(new SimpleDateFormat(dateFormat));
    }

    public static String toLogJson(Object object) {
        JsonMapper jsonMapper = new JsonMapper(Inclusion.NON_DEFAULT);
        jsonMapper.setDateFormat("yyyy-MM-dd hh:mm:ss");
        return jsonMapper.toJson(object);
    }
}
